package com.ehotting.edsta.circuitDesign.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ehotting.eaf.core.domain.system.api.SysDictData;
import com.ehotting.eaf.security.service.TokenService;
import com.ehotting.edsta.circuitDesign.bean.Constant;
import com.ehotting.edsta.circuitDesign.bean.request.RequestExecute;
import com.ehotting.edsta.circuitDesign.bean.request.RequestGetCircuitData;
import com.ehotting.edsta.circuitDesign.exception.LoggerAnnotation;
import com.ehotting.edsta.circuitDesign.gen.PropertyFilterHelper;
import com.ehotting.edsta.circuitDesign.mqbd.MqdbRequestDataHelper;
import com.ehotting.edsta.circuitDesign.service.AsyncService;
import com.ehotting.edsta.circuitDesign.service.IEsCircuitService;
import com.ehotting.edsta.circuitDesign.service.IEsGenerateService;
import com.ehotting.eaf.core.constant.HttpStatus;
import com.ehotting.eaf.core.constant.SecurityConstants;
import com.ehotting.eaf.core.domain.R;
import com.ehotting.eaf.core.enums.SimulationTypeEnum;
import com.ehotting.eaf.core.utils.StringUtils;
import com.ehotting.eaf.core.web.controller.BaseController;
import com.ehotting.eaf.core.web.domain.AjaxResult;
import com.ehotting.edsta.common.log.annotation.Log;
import com.ehotting.edsta.common.log.enums.BusinessType;
import com.ehotting.eaf.redis.service.RedisService;
import com.ehotting.edsta.system.api.RemoteDictService;
import com.ehotting.mqbd.api.MqDataStateConstants;
import com.ehotting.mqbd.api.TaskStateActionConstants;
import com.ehotting.mqbd.api.bean.MQDataAble;
import com.ehotting.mqbd.api.bean.MQHttpData;
import com.ehotting.mqbd.api.bean.MqApplicationContext;
import com.ehotting.mqbd.core.manager.AgentLinkManager;
import com.ehotting.mqbd.core.service.MQService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.FutureTask;

@RestController
@RequestMapping("/generate")
public class EsGenerateController extends BaseController {

    @Autowired
    private IEsGenerateService esGenerateService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private IEsCircuitService esSceneService;

    @Autowired
    private AgentLinkManager agentLinkManager;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private AsyncService asyncService;

    @Autowired
    private MqApplicationContext mqApplicationContext;
    @Autowired
    private RemoteDictService remoteDictService;
    @Autowired
    private PropertyFilterHelper propertyFilterHelper;

    @Log(title = SimulationTypeEnum.CIRCUIT_DESIGN_NAME,businessType = BusinessType.OTHER)
    @LoggerAnnotation(description = "获取页面参数数据（交互一）")
    @ApiOperation("获取页面参数数据（交互一）")
    @GetMapping("dictData")
    public R getDictData()
    {

        // 找出所有页面参数
        List<SysDictData> sysDictDataList = getDictData("expert_page_param_config");

        ArrayList<Map<String,Object>> dataMap = new ArrayList<>();
        ArrayList<Map<String,Object>> nameMap = new ArrayList<>();
        Map<String, Object> objectMap = new LinkedHashMap<>();

        // 组装每个参数的下拉框数据
        for (SysDictData sysDictData : sysDictDataList){
            String dictType = sysDictData.getDictValue();
            List<SysDictData> paramList = getDictData(dictType);

            // 组装单个参数的下拉框数据
            List<Object> objectList = new ArrayList<>();
            for (SysDictData param : paramList){
                Map<String, Object> paramMap = new LinkedHashMap<>();
                paramMap.put("code", param.getDictValue());
                paramMap.put("name", param.getDictLabel());
                objectList.add(paramMap);
            }

            String[] arr = dictType.split("_");
            String dictTypeKey = arr[arr.length-1];

            HashMap<String, Object> dataHashMap = new HashMap<>();
            dataHashMap.put(dictTypeKey,objectList);
            dataMap.add(dataHashMap);


            HashMap<String, Object> nameHashMap = new LinkedHashMap<>();
            nameHashMap.put(dictTypeKey,sysDictData.getDictLabel());
            nameHashMap.put("remark",sysDictData.getRemark());
            nameMap.add(nameHashMap);

        }

        Object[] dataArray = dataMap.toArray();
        Object[] nameArray = nameMap.toArray();
        objectMap.put("value",dataArray);
        objectMap.put("label",nameArray);
        logger.info("交互一数据组装：{}",JSONObject.toJSONString(objectMap));
        return R.ok(JSONObject.toJSONString(objectMap));

    }


//    @Log(title = SimulationTypeEnum.CIRCUIT_DESIGN_NAME,businessType = BusinessType.OTHER)
//    @LoggerAnnotation(description = "生成电路数据（交互二）(c#)")
//    @ApiOperation("生成电路数据（交互二）(c#)")
//    @PostMapping("/circuitGeneration")
//    public Object circuitGeneration(@RequestBody String value,HttpServletRequest request)
//    {
//
//        logger.info("value:{}" , value);
//        JSONObject jsonObject = JSONObject.parseObject(value);
//        String input = jsonObject.getString("param");
//
//        logger.info("input:{}" , input);
//
//        String onlyIdentity = request.getHeader("serial");
//        return esGenerateService.circuitGeneration(input,onlyIdentity);
//
//    }

    @Log(title = SimulationTypeEnum.CIRCUIT_DESIGN_NAME,businessType = BusinessType.OTHER)
    @ApiOperation("生成电路数据（交互二）(c#)")
    @LoggerAnnotation(description = "生成电路数据（交互二）(c#)")
    @PostMapping("/circuitGeneration")
    public R circuitGeneration(@RequestBody String value,HttpServletRequest request)
    {
        JSONObject jsonObject = JSONObject.parseObject(value);
        if(!StringUtils.isEmpty(jsonObject.getString("param3"))) {
            MQHttpData data = MqdbRequestDataHelper.rePost(
                    mqApplicationContext,
                    "circuitDesign:11-10",
                    "Authorization",
                    new JSONObject(),
                    "serial");
            asyncService.testCancelTask(data);
            return R.okMsg(JSON.toJSONString(data.getMsg()));
        }
        if(!StringUtils.isEmpty(jsonObject.getString("param2"))) {
            MQHttpData data = MqdbRequestDataHelper.rePost(
                    mqApplicationContext,
                    "circuitDesign:11-10",
                    "Authorization",
                    new JSONObject(),
                    "serial");
            asyncService.asyncTask(data);
            return R.okMsg(JSON.toJSONString(data.getMsg()));
        }
        if(!StringUtils.isEmpty(jsonObject.getString("param1"))) {
            return R.okMsg("求解活动进入排队中");
        }

        String input = jsonObject.getString("param");
        if(StringUtils.isEmpty(input)) return R.fail("args is error");
        logger.info("\n杨帆启航\n");


        String serial = request.getHeader("serial");
        JSONObject rePostBody = new JSONObject();
        rePostBody.put("serial",serial);
        rePostBody.put("input",input);

        String authorization = request.getHeader("Authorization");
        Long userId = tokenService.getLoginUser().getUserid();
        RequestExecute requestExecute = JSONObject.parseObject(input, RequestExecute.class);
        String mainProjectId = requestExecute.getMainProjectId();
        String agentId = agentLinkManager.genAgentId(mqApplicationContext.getModule(),userId,mainProjectId);

        MQHttpData data = MqdbRequestDataHelper.rePost(mqApplicationContext,agentId,authorization,rePostBody,serial);
        asyncService.asyncTask(data);


        return R.okMsg("\n\n"+mainProjectId+"\t杨帆启航\n");
    }


    @Log(title = SimulationTypeEnum.CIRCUIT_DESIGN_NAME,businessType = BusinessType.OTHER)
    @ApiOperation("生成电路数据（交互二）(mq)")
    @LoggerAnnotation(description = "生成电路数据（交互二）(mq)")
    @PostMapping("/circuitGeneration2")
    public R circuitGeneration2(@RequestBody JSONObject jsonObject)
    {
        logger.info("\n\n抵达世界尽头--码头\n\n");
        if(jsonObject == null){
            return R.okMsg("参数有误");
        }

        String input = jsonObject.getString("input");
        logger.info("input:{}",input);

        return esGenerateService.circuitGeneration(input);
    }

    @ApiOperation("匹配停止")
    @LoggerAnnotation(description = "匹配停止")
    @PostMapping("/KillCircuitGenerationThread")
    public Object KillCircuitGenerationThread(@RequestBody String mainProjectId,HttpServletRequest request) {
        // 未进行求解，取消排队
        String authorization = request.getHeader("Authorization");
        Long userId = tokenService.getLoginUser().getUserid();
        String serial = request.getHeader("serial");
        String agentId = agentLinkManager.genAgentId(mqApplicationContext.getModule(), userId, mainProjectId);
        JSONObject rePostBody = new JSONObject();
        rePostBody.put("msg", "匹配停止");
        rePostBody.put("mainProjectId", mainProjectId);

        MQHttpData mqData = MqdbRequestDataHelper.taskCancel(mqApplicationContext, agentId, authorization, rePostBody, serial);

        MQHttpData responseMQData = asyncService.cancelTask(mqData);

        redisService.set(Constant.Kill_Circuit_Generation_Thread + mainProjectId, "false");

        return responseMQData.getResponse().getResponse();
    }

    @ApiOperation("匹配停止")
    @LoggerAnnotation(description = "匹配停止")
    @PostMapping("/KillCircuitGenerationThread2")
    public R KillCircuitGenerationThread2(@RequestBody JSONObject jsonObject)
    {
//        String mainProjectId = jsonObject.getString("mainProjectId");
//        redisService.set(Constant.Kill_Circuit_Generation_Thread+mainProjectId,"false");

        return R.okMsg("正在停止匹配,请耐心等待......😊😊");
    }

    @Log(title = SimulationTypeEnum.CIRCUIT_DESIGN_NAME,businessType = BusinessType.OTHER)
    @LoggerAnnotation(description = "获取电路数据（交互三）")
    @ApiOperation("获取电路数据（交互三）")
    @PostMapping("/getCircuitData")
    public R getCircuitData(@RequestBody RequestGetCircuitData requestGetCircuitData,HttpServletRequest request)
    {

        if (requestGetCircuitData == null) return R.fail("data is null");

        logger.info("getCircuitData request:{}", JSONObject.toJSONString(requestGetCircuitData));

        if (StringUtils.isEmpty(requestGetCircuitData.getId())) return R.fail("id is null");

        if (requestGetCircuitData.getPage() == 0) requestGetCircuitData.setPage(1);

        if (requestGetCircuitData.getPageSize() == 0) requestGetCircuitData.setPageSize(20);

        String authorization = request.getHeader("Authorization");
        return esGenerateService.getCircuitData(requestGetCircuitData,authorization);
    }

    @ApiOperation("推理规则")
    @PostMapping("execute")
    public AjaxResult execute(Long sceneId, Long ruleId, Map<String,Object> params)
    {
        return AjaxResult.success("", esSceneService.execute(sceneId, ruleId, params));
    }

    /**
     * 参数过滤提示
     * @param value
     * @return
     */
    @LoggerAnnotation(description = "参数过滤提示")
    @PostMapping("/paramTips")
    public R paramTips(@RequestBody String value)
    {

        JSONObject jsonObject = JSONObject.parseObject(value);
        String param = jsonObject.getString("param");
        String mainProjectId = jsonObject.getString("mainProjectId");
        if(StringUtils.isEmpty(param) || StringUtils.isEmpty(mainProjectId)){
            return R.fail("args is error");
        }
        return propertyFilterHelper.filterCircuit(param,mainProjectId);
    }

    private List<SysDictData> getDictData(String dictType){
        List<SysDictData> sysDictDataList = new ArrayList<>();

        AjaxResult result = remoteDictService.dictType(dictType, SecurityConstants.INNER);
        if (result.get(AjaxResult.CODE_TAG).toString().equals(String.valueOf(HttpStatus.ERROR))){
            return sysDictDataList;
        }

        if (result.get(AjaxResult.DATA_TAG) == null){
            return sysDictDataList;
        }

        String json = JSONObject.toJSONString(result.get(AjaxResult.DATA_TAG));
        sysDictDataList = JSONObject.parseArray(json, SysDictData.class);
        return sysDictDataList;
    }

}
